Consider the following query
SELECT * FROM table_name WHERE col1 oper ( SELECT .... )
col1
is indexed, and we are expecting Oracle to evaluate the sub-query and use the result to perform an indexed lookup on table_name
.
This is quite feasible, but only under some conditions:
Examples of queries that may use an index (indexed column underlined)
Select sales for the 5th financial month of 2003
SELECT * FROM sales WHERE saledate in ( SELECT calendar_date FROM calendar WHERE financial_month = 5 AND financial_year = 2003)
Select employees who work in the same department as Jones.
SELECT * FROM emp WHERE deptnum = ( SELECT deptnum FROM emp WHERE emp_name = 'JONES')
Examples of queries that will not use an index.
Employees paid more than the company average salary
SELECT * FROM emp WHERE sal > ( SELECT avg(sal) FROM emp)
Employees paid more than the highest departmental average
SELECT * FROM emp WHERE sal > ALL ( SELECT avg(sal) FROM emp GROUP BY deptnum)
NOT IN sub-query | Sorry, there is simply no way to index this. If the outer table is large and you have no other indexed columns you can access, then you have a High Volume query. You can probably still tune it, but you may never get lightning performance. |
{>|<}[=] [ANY|ALL] sub-query | A normal Note that this work-around will not work for hash clusters which can only ever be scanned with equals or IN operators. |
correlated sub-query | If you really want indexed access on the outer table, you must rewrite the SQL to avoid the correlated sub-query. This may be possible by performing a join instead of a sub-query, or using an uncorrelated IN sub-query in place of an equals (=) sub-query. |